<script lang="ts">
export default async function () {
	if (!window.Vuex) {
		/**
		 * vuex v2.0.0
		 * (c) 2016 Evan You
		 * @license MIT
		 */
		(function (factory) {
			window.Vuex = factory();
		})(function () {
			"use strict";

			var devtoolHook = typeof window !== "undefined" && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;

			function devtoolPlugin(store) {
				if (!devtoolHook) {
					return;
				}

				store._devtoolHook = devtoolHook;

				devtoolHook.emit("vuex:init", store);

				devtoolHook.on("vuex:travel-to-state", function (targetState) {
					store.replaceState(targetState);
				});

				store.subscribe(function (mutation, state) {
					devtoolHook.emit("vuex:mutation", mutation, state);
				});
			}

			function applyMixin(Vue) {
				var version = Number(Vue.version.split(".")[0]);

				if (version >= 2) {
					var usesInit = Vue.config._lifecycleHooks.indexOf("init") > -1;
					Vue.mixin(usesInit ? { init: vuexInit } : { beforeCreate: vuexInit });
				} else {
					// override init and inject vuex init procedure
					// for 1.x backwards compatibility.
					var _init = Vue.prototype._init;
					Vue.prototype._init = function (options) {
						if (options === void 0) options = {};

						options.init = options.init ? [vuexInit].concat(options.init) : vuexInit;
						_init.call(this, options);
					};
				}

				/**
				 * Vuex init hook, injected into each instances init hooks list.
				 */

				function vuexInit() {
					var options = this.$options;
					// store injection
					if (options.store) {
						this.$store = options.store;
					} else if (options.parent && options.parent.$store) {
						this.$store = options.parent.$store;
					}
				}
			}

			function mapState(states) {
				var res = {};
				normalizeMap(states).forEach(function (ref) {
					var key = ref.key;
					var val = ref.val;

					res[key] = function mappedState() {
						return typeof val === "function"
							? val.call(this, this.$store.state, this.$store.getters)
							: this.$store.state[val];
					};
				});
				return res;
			}

			function mapMutations(mutations) {
				var res = {};
				normalizeMap(mutations).forEach(function (ref) {
					var key = ref.key;
					var val = ref.val;

					res[key] = function mappedMutation() {
						var args = [],
							len = arguments.length;
						while (len--) args[len] = arguments[len];

						return this.$store.commit.apply(this.$store, [val].concat(args));
					};
				});
				return res;
			}

			function mapGetters(getters) {
				var res = {};
				normalizeMap(getters).forEach(function (ref) {
					var key = ref.key;
					var val = ref.val;

					res[key] = function mappedGetter() {
						if (!(val in this.$store.getters)) {
							console.error("[vuex] unknown getter: " + val);
						}
						return this.$store.getters[val];
					};
				});
				return res;
			}

			function mapActions(actions) {
				var res = {};
				normalizeMap(actions).forEach(function (ref) {
					var key = ref.key;
					var val = ref.val;

					res[key] = function mappedAction() {
						var args = [],
							len = arguments.length;
						while (len--) args[len] = arguments[len];

						return this.$store.dispatch.apply(this.$store, [val].concat(args));
					};
				});
				return res;
			}

			function normalizeMap(map) {
				return Array.isArray(map)
					? map.map(function (key) {
							return { key: key, val: key };
						})
					: Object.keys(map).map(function (key) {
							return { key: key, val: map[key] };
						});
			}

			function isObject(obj) {
				return obj !== null && typeof obj === "object";
			}

			function isPromise(val) {
				return val && typeof val.then === "function";
			}

			function assert(condition, msg) {
				if (!condition) {
					throw new Error("[vuex] " + msg);
				}
			}

			var Vue; // bind on install

			var Store = function Store(options) {
				var this$1 = this;
				if (options === void 0) options = {};

				assert(Vue, "must call Vue.use(Vuex) before creating a store instance.");
				assert(
					typeof Promise !== "undefined",
					"vuex requires a Promise polyfill in this browser."
				);

				var state = options.state;
				if (state === void 0) state = {};
				var plugins = options.plugins;
				if (plugins === void 0) plugins = [];
				var strict = options.strict;
				if (strict === void 0) strict = false;

				// store internal state
				this._options = options;
				this._committing = false;
				this._actions = Object.create(null);
				this._mutations = Object.create(null);
				this._wrappedGetters = Object.create(null);
				this._runtimeModules = Object.create(null);
				this._subscribers = [];
				this._watcherVM = new Vue();

				// bind commit and dispatch to self
				var store = this;
				var ref = this;
				var dispatch = ref.dispatch;
				var commit = ref.commit;
				this.dispatch = function boundDispatch(type, payload) {
					return dispatch.call(store, type, payload);
				};
				this.commit = function boundCommit(type, payload, options) {
					return commit.call(store, type, payload, options);
				};

				// strict mode
				this.strict = strict;

				// init root module.
				// this also recursively registers all sub-modules
				// and collects all module getters inside this._wrappedGetters
				installModule(this, state, [], options);

				// initialize the store vm, which is responsible for the reactivity
				// (also registers _wrappedGetters as computed properties)
				resetStoreVM(this, state);

				// apply plugins
				plugins.concat(devtoolPlugin).forEach(function (plugin) {
					return plugin(this$1);
				});
			};

			var prototypeAccessors = { state: {} };

			prototypeAccessors.state.get = function () {
				return this._vm.state;
			};

			prototypeAccessors.state.set = function (v) {
				assert(false, "Use store.replaceState() to explicit replace store state.");
			};

			Store.prototype.commit = function commit(type, payload, options) {
				var this$1 = this;

				// check object-style commit
				if (isObject(type) && type.type) {
					options = payload;
					payload = type;
					type = type.type;
				}
				var mutation = { type: type, payload: payload };
				var entry = this._mutations[type];
				if (!entry) {
					console.error("[vuex] unknown mutation type: " + type);
					return;
				}
				this._withCommit(function () {
					entry.forEach(function commitIterator(handler) {
						handler(payload);
					});
				});
				if (!options || !options.silent) {
					this._subscribers.forEach(function (sub) {
						return sub(mutation, this$1.state);
					});
				}
			};

			Store.prototype.dispatch = function dispatch(type, payload) {
				// check object-style dispatch
				if (isObject(type) && type.type) {
					payload = type;
					type = type.type;
				}
				var entry = this._actions[type];
				if (!entry) {
					console.error("[vuex] unknown action type: " + type);
					return;
				}
				return entry.length > 1
					? Promise.all(
							entry.map(function (handler) {
								return handler(payload);
							})
						)
					: entry[0](payload);
			};

			Store.prototype.subscribe = function subscribe(fn) {
				var subs = this._subscribers;
				if (subs.indexOf(fn) < 0) {
					subs.push(fn);
				}
				return function () {
					var i = subs.indexOf(fn);
					if (i > -1) {
						subs.splice(i, 1);
					}
				};
			};

			Store.prototype.watch = function watch(getter, cb, options) {
				var this$1 = this;

				assert(typeof getter === "function", "store.watch only accepts a function.");
				return this._watcherVM.$watch(
					function () {
						return getter(this$1.state);
					},
					cb,
					options
				);
			};

			Store.prototype.replaceState = function replaceState(state) {
				var this$1 = this;

				this._withCommit(function () {
					this$1._vm.state = state;
				});
			};

			Store.prototype.registerModule = function registerModule(path, module) {
				if (typeof path === "string") {
					path = [path];
				}
				assert(Array.isArray(path), "module path must be a string or an Array.");
				this._runtimeModules[path.join(".")] = module;
				installModule(this, this.state, path, module);
				// reset store to update getters...
				resetStoreVM(this, this.state);
			};

			Store.prototype.unregisterModule = function unregisterModule(path) {
				var this$1 = this;

				if (typeof path === "string") {
					path = [path];
				}
				assert(Array.isArray(path), "module path must be a string or an Array.");
				delete this._runtimeModules[path.join(".")];
				this._withCommit(function () {
					var parentState = getNestedState(this$1.state, path.slice(0, -1));
					Vue.delete(parentState, path[path.length - 1]);
				});
				resetStore(this);
			};

			Store.prototype.hotUpdate = function hotUpdate(newOptions) {
				updateModule(this._options, newOptions);
				resetStore(this);
			};

			Store.prototype._withCommit = function _withCommit(fn) {
				var committing = this._committing;
				this._committing = true;
				fn();
				this._committing = committing;
			};

			Object.defineProperties(Store.prototype, prototypeAccessors);

			function updateModule(targetModule, newModule) {
				if (newModule.actions) {
					targetModule.actions = newModule.actions;
				}
				if (newModule.mutations) {
					targetModule.mutations = newModule.mutations;
				}
				if (newModule.getters) {
					targetModule.getters = newModule.getters;
				}
				if (newModule.modules) {
					for (var key in newModule.modules) {
						if (!(targetModule.modules && targetModule.modules[key])) {
							console.warn(
								"[vuex] trying to add a new module '" +
									key +
									"' on hot reloading, " +
									"manual reload is needed"
							);
							return;
						}
						updateModule(targetModule.modules[key], newModule.modules[key]);
					}
				}
			}

			function resetStore(store) {
				store._actions = Object.create(null);
				store._mutations = Object.create(null);
				store._wrappedGetters = Object.create(null);
				var state = store.state;
				// init root module
				installModule(store, state, [], store._options, true);
				// init all runtime modules
				Object.keys(store._runtimeModules).forEach(function (key) {
					installModule(store, state, key.split("."), store._runtimeModules[key], true);
				});
				// reset vm
				resetStoreVM(store, state);
			}

			function resetStoreVM(store, state) {
				var oldVm = store._vm;

				// bind store public getters
				store.getters = {};
				var wrappedGetters = store._wrappedGetters;
				var computed = {};
				Object.keys(wrappedGetters).forEach(function (key) {
					var fn = wrappedGetters[key];
					// use computed to leverage its lazy-caching mechanism
					computed[key] = function () {
						return fn(store);
					};
					Object.defineProperty(store.getters, key, {
						get: function () {
							return store._vm[key];
						}
					});
				});

				// use a Vue instance to store the state tree
				// suppress warnings just in case the user has added
				// some funky global mixins
				var silent = Vue.config.silent;
				Vue.config.silent = true;
				store._vm = new Vue({
					data: { state: state },
					computed: computed
				});
				Vue.config.silent = silent;

				// enable strict mode for new vm
				if (store.strict) {
					enableStrictMode(store);
				}

				if (oldVm) {
					// dispatch changes in all subscribed watchers
					// to force getter re-evaluation.
					store._withCommit(function () {
						oldVm.state = null;
					});
					Vue.nextTick(function () {
						return oldVm.$destroy();
					});
				}
			}

			function installModule(store, rootState, path, module, hot) {
				var isRoot = !path.length;
				var state = module.state;
				var actions = module.actions;
				var mutations = module.mutations;
				var getters = module.getters;
				var modules = module.modules;

				// set state
				if (!isRoot && !hot) {
					var parentState = getNestedState(rootState, path.slice(0, -1));
					var moduleName = path[path.length - 1];
					store._withCommit(function () {
						Vue.set(parentState, moduleName, state || {});
					});
				}

				if (mutations) {
					Object.keys(mutations).forEach(function (key) {
						registerMutation(store, key, mutations[key], path);
					});
				}

				if (actions) {
					Object.keys(actions).forEach(function (key) {
						registerAction(store, key, actions[key], path);
					});
				}

				if (getters) {
					wrapGetters(store, getters, path);
				}

				if (modules) {
					Object.keys(modules).forEach(function (key) {
						installModule(store, rootState, path.concat(key), modules[key], hot);
					});
				}
			}

			function registerMutation(store, type, handler, path) {
				if (path === void 0) path = [];

				var entry = store._mutations[type] || (store._mutations[type] = []);
				entry.push(function wrappedMutationHandler(payload) {
					handler(getNestedState(store.state, path), payload);
				});
			}

			function registerAction(store, type, handler, path) {
				if (path === void 0) path = [];

				var entry = store._actions[type] || (store._actions[type] = []);
				var dispatch = store.dispatch;
				var commit = store.commit;
				entry.push(function wrappedActionHandler(payload, cb) {
					var res = handler(
						{
							dispatch: dispatch,
							commit: commit,
							getters: store.getters,
							state: getNestedState(store.state, path),
							rootState: store.state
						},
						payload,
						cb
					);
					if (!isPromise(res)) {
						res = Promise.resolve(res);
					}
					if (store._devtoolHook) {
						return res.catch(function (err) {
							store._devtoolHook.emit("vuex:error", err);
							throw err;
						});
					} else {
						return res;
					}
				});
			}

			function wrapGetters(store, moduleGetters, modulePath) {
				Object.keys(moduleGetters).forEach(function (getterKey) {
					var rawGetter = moduleGetters[getterKey];
					if (store._wrappedGetters[getterKey]) {
						console.error("[vuex] duplicate getter key: " + getterKey);
						return;
					}
					store._wrappedGetters[getterKey] = function wrappedGetter(store) {
						return rawGetter(
							getNestedState(store.state, modulePath), // local state
							store.getters, // getters
							store.state // root state
						);
					};
				});
			}

			function enableStrictMode(store) {
				store._vm.$watch(
					"state",
					function () {
						assert(
							store._committing,
							"Do not mutate vuex store state outside mutation handlers."
						);
					},
					{ deep: true, sync: true }
				);
			}

			function getNestedState(state, path) {
				return path.length
					? path.reduce(function (state, key) {
							return state[key];
						}, state)
					: state;
			}

			function install(_Vue) {
				if (Vue) {
					console.error(
						"[vuex] already installed. Vue.use(Vuex) should be called only once."
					);
					return;
				}
				Vue = _Vue;
				applyMixin(Vue);
			}

			// auto install in dist mode
			if (typeof window !== "undefined" && window.Vue) {
				install(window.Vue);
			}

			var index = {
				Store: Store,
				install: install,
				mapState: mapState,
				mapMutations: mapMutations,
				mapGetters: mapGetters,
				mapActions: mapActions
			};

			return index;
		});
	}

	return window.Vuex;
}
</script>
